/*
*************1. Introduction to the Standard Template Library
The Standard Template Library, or STL, is a C++ library of container classes, algorithms, and iterators; it provides many of the basic algorithms and data structures of computer science. The STL is a generic library, meaning that its components are heavily parameterized: almost every component in the STL is a template. You should make sure that you understand how templates work in C++ before you use the STL.

*************2. Containers and algorithms
Like many class libraries, the STL includes container classes: classes whose purpose is to contain other objects. The STL includes the classes vector, list, deque, set, multiset, map, multimap, hash_set, hash_multiset, hash_map, and hash_multimap. Each of these classes is a template, and can be instantiated to contain any type of object. You can, for example, use a vector<int> in much the same way as you would use an ordinary C array, except that vector eliminates the chore of managing dynamic memory allocation by hand.

      vector<int> v(3);            // Declare a vector of 3 elements.
	  v[0] = 7;
	  v[1] = v[0] + 3;
	  v[2] = v[0] + v[1];          // v[0] == 7, v[1] == 10, v[2] == 17  

The STL also includes a large collection of algorithms that manipulate the data stored in containers. You can reverse the order of elements in a vector, for example, by using the reverse algorithm. 

      reverse(v.begin(), v.end()); // v[0] == 17, v[1] == 10, v[2] == 7

There are two important points to notice about this call to reverse. First, it is a global function, not a member function. Second, it takes two arguments rather than one: it operates on a range of elements, rather than on a container. In this particular case the range happens to be the entire container v.

The reason for both of these facts is the same: reverse, like other STL algorithms, is decoupled from the STL container classes. This means that reverse can be used not only to reverse elements in vectors, but also to reverse elements in lists, and even elements in C arrays. The following program is also valid.

      double A[6] = { 1.2, 1.3, 1.4, 1.5, 1.6, 1.7 };
      reverse(A, A + 6);
      for (int i = 0; i < 6; ++i)
        cout << "A[" << i << "] = " << A[i];

This example uses a range, just like the example of reversing a vector: the first argument to reverse is a pointer to the beginning of the range, and the second argument points one element past the end of the range. This range is denoted [A, A + 6); the asymmetrical notation is a reminder that the two endpoints are different, that the first is the beginning of the range and the second is one past the end of the range. 
*/

#include <algorithm>
#include <vector>
#include <iterator>
#include <iostream>
using namespace std ;

int main ( )
{
	vector<int> v(3) ;
	for(int i=0; i < 3; i++)
		v[i] = i ;

	double A[6] ;
	for(int i=0; i < 6; i++)
		A[i] = 1.0/(i+1) ;
	
	copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ")) ;
	cout<< endl ;

	copy(A, A+6, ostream_iterator<double>(cout, " ")) ; //Pointers themselves are iterators. So STL algorithm can operate on ordinary arrays.
	cout<< endl << "-----After Reverse-----" << endl ;

	reverse(v.begin(), v.end()) ;
	reverse(A, A+6) ;
	copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ")) ;
	cout<< endl ;
	copy(A, A+6, ostream_iterator<double>(cout, " ")) ;
	cout<< endl ;

	return 0 ;
}

